"""
该文件用于 用例的前置和后置条件
"""
import os
import copy
import json
import sys
import time
import pytest
import constant
from common.soft_operate import close_app_kill
from utils.utils_file import move_file
from utils.utils_log import loggerCase
from utils.utils_json import set_json

from utils.utils_operation import auto_close_info

sys.path.append(os.path.dirname(os.path.dirname(__file__)))

result = {}
test = {}
result_path_json = constant.result_json_Path
basePath = constant.base_path
time_json_path = constant.time_json_path


# @pytest.hookimpl装饰器可以将函数注册为pytest钩子的实现——pytest在适当的时候会调用该函数，从而出发自定义的行为
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    """
    测试执行期间收集测试结果信息并生成报告
    收集内容：用例名称、用例结果、用例开始时间、用例结束时间
    """
    global result
    current_path = os.getcwd()
    os.chdir(basePath)
    '''
    setup->call->teardown
    '''
    out = yield  # 通过yield语句，可以在调用其他同名钩子函数之前或之后执行额外的逻辑
    task_id = None
    try:
        with open(constant.taskId_path, 'r') as f:
            task_id = f.readline()
            print("task_id:", task_id)
    except:
        print('本地不存在task_id文件')

    report = out.get_result()
    if report.when not in result.keys():
        result[report.when] = report.outcome  # 统计每个用例执行步骤的名称及结果

    # 在teardown的之后开始收集数据
    if report.when == 'teardown':
        loggerCase.debug("开始收集conftest的teardown")
        result_content = {}
        test_result = {}
        try:
            with open(result_path_json, 'r', encoding="utf-8") as f:  # 读取之前用例的执行json结果
                test_result = json.load(f)
        except:
            print("本次结果记录的json为空")

        # if "task_id.txt" not in test_result.keys() and task_id.txt is not None:
        #     test_result["task_id.txt"] = task_id.txt
        # else:
        #     print("task_id已存在test_result中！！！")
        test_result["task_id"] = task_id

        if "failed" not in result.values():  # 判断failed的这个结果是否存在在此条用例执行过程中
            result_content["result"] = "passed"
        else:
            result_content["result"] = "failed"
        fun_name = report.nodeid.split("::")[-1]  # 截取本条用例执行名称
        with open(time_json_path, 'r') as f:  # 读取在setup和teardown中保存的start_time和end_time
            time_jsons = json.load(f)
            result_content["start_time"] = time_jsons["start_time"]
            result_content["end_time"] = time_jsons["end_time"]
            # fun_name = fun_name+time_json['moudle_name']

            list = [file for file in os.listdir(os.path.join('..', os.path.dirname(constant.base_path), 'static')) if
                    file.startswith("Scan_")]
            if len(list) > 0:
                path = os.path.join('..', os.path.dirname(constant.base_path), 'static')
                time = time_jsons['start_time'].replace("-", "").replace(" ", "_").replace(":", "")
                move_file(os.path.join(path, list[0]),
                          os.path.join(path, f"{time}.xls"))

        test_result[fun_name] = result_content

        with open(result_path_json, 'w', encoding="utf-8") as f:
            f.write(json.dumps(test_result))  # 将最后本条用例的结果保存到json中
        result = {}
        if constant.exit_flag:
            auto_close_info(message="跑机失败")
            pytest.exit("根据需求,跑机失败,立即停止")
    os.chdir(current_path)


def pytest_configure(config):
    """
    自定义修改测试报告生成路径及名称
    """
    # 更改测试报告路径
    # 定义报告的文件名
    test_result = {}
    var = constant.test_report_ui_path.split('\\')

    # if not os.path.exists(constant.taskId_path):
    #     report_path = constant.test_report_ui_path + os.sep + config.getoption('--reportName') + '-' + str(
    #         time.strftime(f"%Y_%m_%d_%H_%M", time.localtime(
    #             time.time()))) + '.html'
    # else:
    #     report_old_path = os.path.join(
    #         '..', 'static', var[-1])
    #     report_path = report_old_path + os.sep + config.getoption('--reportName') + '-' + str(
    #         time.strftime(f"%Y_%m_%d_%H_%M", time.localtime(
    #             time.time()))) + '.html'
    report_path = os.path.join(constant.test_report_ui_path, "index.html")

    config.option.reportPath = constant.test_report_ui_path

    # if report_path:
    #     report_dir = os.path.dirname(report_path)  # 返回指定路径的父目录路径
    #     report_name = os.path.basename(report_path)  # 返回指定路径的基本文件名
    #     config.option.htmlpath = report_path
    #     # config.option.reportName = report_name
    #     config.option.reportPath = report_dir

    test_result["summary_folder"] = report_path
    with open(result_path_json, 'w', encoding="utf-8") as f:
        f.write(json.dumps(test_result))

    # 修改用例的筛选条件
    caseTitle = config.getoption(f"--{'caseTitle'}")
    caseType = config.getoption(f"--{'caseType'}")
    caseLevel = config.getoption(f"--{'caseLevel'}")
    screening_data = {
        "case_title": caseTitle,
        "tb_level": caseLevel,
        "tb_type": caseType
    }
    set_json(screening_data, constant.screening_conditions_json_path)


@pytest.hookimpl(tryfirst=True)
def pytest_runtest_logreport(report):
    def handle_result(result_state):

        report.info_logs = "\n".join(loggerCase.get_info_level_log())  # pt-testreport测试报告里面用的到 运行日志
        report.image_logs = copy.deepcopy(loggerCase.get_image_log())  # pt-testreport测试报告里面用的到 调试信息

    report.method = (report.method).replace(".", "::")
    # 构建测试平台需要的信息
    # if report.desc:
    #     report.desc = report.desc.encode("utf-8").decode("unicode_escape")

    # case.current_case_name = report.desc

    # 下面这样写的必要性：call代表用例执行的状态  但是setup或者teardown也有可能执行失败， 因此需要多加一层判断 report.outcome == "failed"
    if report.when == 'call':
        handle_result(report.outcome)
    elif report.outcome == "failed":
        handle_result(report.outcome)
    elif report.outcome == "skipped":
        handle_result(report.outcome)

        # if report.outcome == "failed":
        #     loggerCase.error('test_case failed screen', extra={'image_path': MainPage().print_screen()})


def pytest_runtest_teardown(item):
    # socketClient.sendall(f'{case.case_result_record}'.encode())
    loggerCase.log_records.clear()
    # send_result_to_test_platform({case.current_case_name: case.current_case_info})


def pytest_unconfigure(config):
    """
    所有用例执行完后操作
    :param config:
    :return:
    """
    loggerCase.info("===============关闭软件=====================")
    # close_app_kill()



# @pytest.fixture(scope="session", autouse=True)
# def prepare_data():
#     """
#     准备数据
#     :return:
#     """
#     loggerCase.info("准备标志点数据")
#     prepare_markers_data()
#     loggerCase.info("准备空白txt")
#     prepare_blank_txt()

@pytest.fixture(scope="function", autouse=True)
def test_case_time():
    """
    测试用例 执行时间
    """
    current_path = os.getcwd()
    os.chdir(basePath)
    testcase_start_time_recording()
    os.chdir(current_path)
    yield
    os.chdir(basePath)
    testcase_end_time_recording()
    os.chdir(current_path)


def testcase_start_time_recording():
    """
       用例开始时间及结束时间记录
       在每个函数执行前自动启动
       """
    # logs().info('用例开始时间记录开始')
    time_json = {}
    try:
        with open(time_json_path, 'r', encoding="utf-8") as f:
            time_json = json.load(f)
    except:
        # logs().info("json为空或不存在")
        print("json为空或不存在")
    time1 = time.time()
    start_time = time.strftime(f"%Y-%m-%d %H:%M:%S", time.localtime(time1))
    time_json["start_time"] = start_time
    with open(time_json_path, 'w', encoding="utf-8") as f:
        f.write(json.dumps(time_json))
    print(f"用例开始时间记录结束：start_time：{start_time}")
    # logs().info(f"用例开始时间记录结束：start_time：{start_time}")
    print(time_json, '-----------------')


def testcase_end_time_recording():
    """
       用例开始时间及结束时间记录
       在每个函数执行前自动启动
    """
    # logs().info('用例结束时间记录开始')
    print('用例结束时间记录开始')
    time.sleep(3)
    time_json = {}
    try:
        with open(time_json_path, 'r', encoding="utf-8") as f:
            time_json = json.load(f)
    except:
        print("json未空或不存在")
    print(time_json, '+++++++++++++')

    # logs().info("json未空或不存在")
    time1 = time.time()
    end_time = time.strftime(f"%Y-%m-%d %H:%M:%S", time.localtime(time1))
    time_json["end_time"] = end_time
    with open(time_json_path, 'w', encoding="utf-8") as f:
        f.write(json.dumps(time_json))
    time.sleep(3)
    print(f"用例结束时间记录结束：end_time：{end_time}")
    # logs().info(f"用例结束时间记录结束：end_time：{end_time}")


def pytest_addoption(parser):
    """
    增加pytest的自定义命令
    """
    parser.addoption("--caseTitle", action="store", default=None, help="执行用例的标题,包含关系")
    parser.addoption("--caseLevel", action="store", default=None, help="用例等级")
    parser.addoption("--caseType", action="store", default=None, help="business：全部流程用例")
